package io.terminus.spzx.common.log.utils;

import com.alibaba.fastjson.JSON;
import io.terminus.spzx.common.log.annotation.SpzxLog;
import io.terminus.spzx.model.entity.system.SysOperLog;
import io.terminus.spzx.utils.AuthContextUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author lichunlong lcl253137@alibaba-inc.com
 * @desc 系统日志工具类
 * @date 2024-10-18
 */
public class LogUtils {

    /**
     * 操作执行之前调用
     *
     * @param sysLog     系统日志
     * @param joinPoint  AOP切入点
     * @param sysOperLog 系统操作日志
     */
    public static void beforeHandleLog(SpzxLog sysLog, ProceedingJoinPoint joinPoint, SysOperLog sysOperLog) {
        // 设置操作模块名称
        sysOperLog.setTitle(sysLog.title());
        sysOperLog.setOperatorType(sysLog.operatorType().name());

        // 获取目标方法信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        sysOperLog.setMethod(method.getDeclaringClass().getName());

        // 获取请求相关参数
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        sysOperLog.setRequestMethod(request.getMethod());
        sysOperLog.setOperUrl(request.getRequestURI());
        sysOperLog.setOperIp(request.getRemoteAddr());

        // 设置请求参数
        if (sysLog.isSaveRequestData()) {
            String requestMethod = sysOperLog.getRequestMethod();
            if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
                String params = Arrays.toString(joinPoint.getArgs());
                sysOperLog.setOperParam(params);
            }
        }
        sysOperLog.setOperName(AuthContextUtil.get().getUserName());
    }

    /**
     * 操作执行之后调用
     *
     * @param sysLog     系统日志
     * @param proceed    AOP处理结果
     * @param sysOperLog 系统操作日志
     * @param status     操作状态
     * @param errorMsg   错误消息
     */
    public static void afterHandleLog(SpzxLog sysLog, Object proceed, SysOperLog sysOperLog, int status, String errorMsg) {
        if (sysLog.isSaveResponseData()) {
            sysOperLog.setJsonResult(JSON.toJSONString(proceed));
        }
        sysOperLog.setStatus(status);
        sysOperLog.setErrorMsg(errorMsg);
    }
}
